package sk.stuba.fiit.npr.la;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LexicalUnitManager {
	private static ArrayList<LexicalUnit> foundUnits;
	private static boolean errorDuringAnalysis = false;
	
	public static void catchLexicalUnits(String urlAddress) {
		ArrayList<String> lexUnits = new ConfLexicalUnits().getlUnits();
		foundUnits = new ArrayList<LexicalUnit>();
		
		String helper = urlAddress;
		for(String lUnit : lexUnits) {
			String helper2 = helper;
			while( -1 != helper2.indexOf(lUnit)) {
				//zisti index
				int index = 0;
				for(LexicalUnit unit : foundUnits) {
					if("http://".equals(unit.getValue()) || "ftp://".equals(unit.getValue()) ||"telnet://".equals(unit.getValue()) || "mailto::".equals(unit.getValue())) {
						index = unit.getLength() + unit.getIndexOfoccurrence();
					} else if(lUnit.equals(unit.getValue())) {
						index = unit.getIndexOfoccurrence() + unit.getLength();
					}
				}//end
				
				int finalIndex = helper2.indexOf(lUnit) + index;
				foundUnits.add(new LexicalUnit(finalIndex, lUnit.length(), lUnit));
//				System.out.println("pridavam: " + lUnit + " na index: " + finalIndex);
				
				if("http://".equals(lUnit) || "ftp://".equals(lUnit) ||"telnet://".equals(lUnit) || "mailto::".equals(lUnit)) {
					String h = helper.substring(0, helper.indexOf(lUnit));
					helper = helper.substring(helper.indexOf(lUnit) + lUnit.length());
					helper = h+helper;
					helper2 = helper;
				} else {
					helper2 =  helper2.substring(helper2.indexOf(lUnit) + lUnit.length());
				}
//				System.out.println("helper> " + helper2);
			}
		}
		
		sort();
		
		ArrayList<LexicalUnit> temp = new ArrayList<LexicalUnit>();
		temp = (ArrayList<LexicalUnit>) foundUnits.clone();
		
//		for(LexicalUnit unit : temp) {
//			System.out.println("TempValue: " + unit.getValue()+ " index: " + unit.getIndexOfoccurrence());
//		}
		
		for(int i = 0; i < temp.size(); i++) {
			if(i+1 < temp.size()) {
				int a = temp.get(i).getIndexOfoccurrence() + temp.get(i).getLength();
				int b = temp.get(i+1).getIndexOfoccurrence();
//				System.out.println(urlAddress.substring(a, b));
				foundUnits.addAll(breakWorsToChars(new LexicalUnit(a, urlAddress.substring(a, b).length(), urlAddress.substring(a, b))));
//				foundUnits.add(new LexicalUnit(a, urlAddress.substring(a, b).length(), urlAddress.substring(a, b)));
			} else {
				int a = temp.get(i).getIndexOfoccurrence() + temp.get(i).getLength();
//				System.out.println(urlAddress.substring(a));
				foundUnits.addAll(breakWorsToChars(new LexicalUnit(a, urlAddress.substring(a).length(), urlAddress.substring(a))));
//				foundUnits.add(new LexicalUnit(a, urlAddress.substring(a).length(), urlAddress.substring(a)));
			}
		}
		
		if(errorDuringAnalysis) {
			foundUnits.removeAll(foundUnits);
			return;
		}
		
		sort();
		
		for(LexicalUnit unit : foundUnits) {
			System.out.println("LexicalUnit: " + unit.getValue()+ " index: " + unit.getIndexOfoccurrence());
		}
		
		
	}
	
	private static void sort() {
		ArrayList<LexicalUnit> temp = new ArrayList<LexicalUnit>();
		int[] indexes = new int[foundUnits.size()];
		int increment = 0;
		for(LexicalUnit unit : foundUnits) {
			indexes[increment++] = unit.getIndexOfoccurrence();
		}
		Arrays.sort(indexes);
		increment = 0;
		while(increment != foundUnits.size()) {
			for(LexicalUnit unit : foundUnits) {
				if(unit.getIndexOfoccurrence() == indexes[increment]) {
					temp.add(unit);
				}
			}
			increment++;
		}
		foundUnits = temp;
//		for(LexicalUnit unit : foundUnits) {
//			System.out.println("SortValue: " + unit.getValue()+ " index: " + unit.getIndexOfoccurrence());
//		}
	}
	
	private static ArrayList<LexicalUnit> breakWorsToChars(LexicalUnit unit) {
		ArrayList<LexicalUnit> temp = new ArrayList<LexicalUnit>();
		for(int i = 0; i < unit.getValue().length(); i++) {
			String s = unit.getValue();
			if(i+1 < unit.getValue().length()) {
				s = s.substring(i, i+1);
				Pattern p = Pattern.compile("\\p{Alnum}");
				Matcher m = p.matcher(s);
				if(!m.matches()) {
					System.out.println("Znak '" + s + "' nie je cislo ani pismeno - nie je lexikalnou jednotkou");
					errorDuringAnalysis = true;
				}
				temp.add(new LexicalUnit(unit.getIndexOfoccurrence() + i, 1, s));
			} else {
				s = s.substring(i);
				Pattern p = Pattern.compile("\\p{Alnum}");
				Matcher m = p.matcher(s);
				if(!m.matches()) {
					System.out.println("Znak '" + s + "' nie je cislo ani pismeno - nie je lexikalnou jednotkou");
					errorDuringAnalysis = true;
				}
				temp.add(new LexicalUnit(unit.getIndexOfoccurrence() + i, 1, s));
			}
		}
		return temp;
	}
	
	public static ArrayList<String> getValues() {
		ArrayList<String> values = new ArrayList<String>();
		for(LexicalUnit unit : foundUnits) {
			values.add(unit.getValue());
		}
//		System.out.println("Values");
//		System.out.println(values);
		values.add("$");
		return values;
	}
}
